package com.example.RTKSDK;

/**
 * NMEA-0183协议数据转换
 */
public class NMEAParser {

    // 解析$xxGGA格式的NMEA数据
    public LocationData parse(String nmeaSentence) {
        if (nmeaSentence == null || nmeaSentence.isEmpty()) {
            return null;
        }
        if (!isValidChecksum(nmeaSentence)) {
            return null;
        }
        String[] fields = nmeaSentence.split(",");

        if ((fields[0].equals("$GPGGA") || fields[0].equals("$GNGGA") || fields[0].equals("$GBGGA")) && fields.length >= 10) {
            return parseGGA(fields);
        }
        return null;
    }

    private LocationData parseGGA(String[] fields) {
        // 纬度 (ddmm.mmmm) + 方向
        double latitude = convertToDecimalDegrees(fields[2], fields[3]);
        // 经度 (dddmm.mmmm) + 方向
        double longitude = convertToDecimalDegrees(fields[4], fields[5]);
        // 海拔高度
        double altitude = parseDoubleSafe(fields[9]);
        // 定位质量
        int fixQuality = parseIntSafe(fields[6]);

        // 转换为CGCS2000坐标系 (此处简化为直接使用WGS84坐标)
        //double[] cgcs2000 = CoordinateConverter.wgs84ToCgcs2000(latitude, longitude, altitude);

        return new LocationData(
                latitude, // 纬度
                longitude, // 经度
                altitude, // 海拔
                System.currentTimeMillis(),
                fixQuality // 定位质量
        );
    }

    // 校验和验证
    private boolean isValidChecksum(String sentence) {
        try {
            int asteriskIndex = sentence.indexOf('*');
            if (asteriskIndex == -1 || asteriskIndex + 3 > sentence.length()) {
                return false;
            }

            String checksumStr = sentence.substring(asteriskIndex + 1, asteriskIndex + 3);
            int expectedChecksum = Integer.parseInt(checksumStr, 16);

            int actualChecksum = 0;
            for (int i = 1; i < asteriskIndex; i++) {
                actualChecksum ^= sentence.charAt(i);
            }

            return actualChecksum == expectedChecksum;
        } catch (Exception e) {
            return false;
        }
    }

    // 安全转换坐标
    private double convertToDecimalDegrees(String coord, String direction) {
        try {
            if (coord.isEmpty()) return 0.0;

            int dotIndex = coord.indexOf('.');
            if (dotIndex < 2) return 0.0; // 确保至少2位数字

            int degrees = Integer.parseInt(coord.substring(0, dotIndex - 2));
            double minutes = Double.parseDouble(coord.substring(dotIndex - 2));

            double decimal = degrees + (minutes / 60.0);

            // 处理方向
            if ("S".equals(direction) || "W".equals(direction)) {
                decimal = -decimal;
            }
            return decimal;
        } catch (Exception e) {
            return 0.0;
        }
    }

    // 安全解析整数
    private int parseIntSafe(String s) {
        if (s == null || s.isEmpty()) return 0;
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    // 安全解析浮点数
    private double parseDoubleSafe(String s) {
        if (s == null || s.isEmpty()) return 0.0;
        try {
            return Double.parseDouble(s);
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }
}
